如果我們要在這樣的場景...
光影自然地掛上一幅《蒙娜麗莎》...
如果你覺得只要把《蒙娜麗莎》稍微變透明再貼上場景的背景即可就太天真了:
為了讓光影變得自然,我們必須借鑑 Photoshop 等圖像處理軟體中常見的功能——圖像混合模式,它是數位影像處理中的一種技術,用來決定兩個圖像如何在一起疊加時產生最終效果。每種混合模式都應用了不同的數學公式,以不同的方式影響圖像的亮度、顏色和對比度。這些模式廣泛應用於平面設計、照片編輯和數位藝術創作中,使得創作者可以實現多樣化的視覺效果,例如增強顏色、創造陰影或高光效果,以及模擬光線的折射和反射。以下是不同混合模式的效果:
詳細的數學公式與 python 實作的程式碼可參考筆者的 Github repo.
每種圖像混合模式獨自應用都顯得不自然,但只要用不同 % 數的透明度將多種圖像混合模式一層一層疊起來就有機會產生出相對自然的光影了! 以下是筆者嘗試出三種不錯的混合模式配方(圖層由上至下):
15% 的 saturation (模糊場景) > 20% 的 screen (模糊場景) > 90% 的 multiply (模糊場景) > 15% 的 exclusion(《蒙娜麗莎》) > 90% 的 overlay (模糊場景) > 《蒙娜麗莎》> 場景
75% 的 overlay (模糊場景) > 50% 的 multiply (模糊場景) > 25 % 的 exclusion (《蒙娜麗莎》) > 《蒙娜麗莎》> 場景
75% 的 saturation (模糊場景) > 40% 的 color_burn (模糊場景) > 90% 的 color (《蒙娜麗莎》) > 55% 的 screen (模糊場景) > 55% 的 multiply (模糊場景) > 《蒙娜麗莎》> 場景
眼尖的人或許會發現除了最底層的場景圖片之外,所有的場景圖都被模糊了,這是為了避免背景的細節 (如磁磚的紋理) 影響《蒙娜麗莎》,因為我們要的只是場景的大致光影而已~ 至於模糊的方法可參考以下函式:
def blurred(image: Image) -> Image:
kernel_size = min(image.size) // 234
kernel_size += 1 if kernel_size % 2 == 0 else 0
return image.filter(ImageFilter.GaussianBlur(kernel_size))
kernel_size
是應用高斯模糊時的參數,它決定了模糊的強度。這裡的 kernel_size
是根據圖像的最小邊長(寬或高)除以 234 來計算的,也就是說圖像越大,模糊的程度會越高。
此外,高斯模糊的核大小必須是奇數。所以要檢查計算出來的 kernel_size
是否為偶數,如果是偶數,則加 1,使其變為奇數 (高斯模糊需要中心像素點,所以必須使用奇數大小的核)。
最後,對圖像應用 PIL 庫中的 GaussianBlur 濾鏡,使用計算出的 kernel_size 作為模糊半徑,並返回模糊處理後的圖像。